#include <stdio.h>
#include <string.h> 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include "ddebug.h"
#include "global_data.h"
#include "message_recv.h"
#include "shmctl.h"
//////////////////////////////////
static struct shm_addr *shm_buf;
static int key2;
static int semid,shmid;
///////////////////////////////////

static int sem_p(int semid, int num)
{
	struct sembuf mybuf;
	mybuf.sem_num = num;
	mybuf.sem_op = -1;
	mybuf.sem_flg = SEM_UNDO;
	if(semop(semid, &mybuf, 1) < 0)
	{
		syserr("semop");
		exit(1);
	}

	return 0;
}

static int sem_v(int semid, int num)
{
	struct sembuf mybuf;
	mybuf.sem_num = num;
	mybuf.sem_op = 1;
	mybuf.sem_flg = SEM_UNDO;
	if(semop(semid, &mybuf, 1) < 0)
	{
		syserr("semop");
		exit(1);
	}

	return 0;
}

/*
 *所有值全为静态局部变量，外部想要获取共享内存，
 *直接返回共享内存地址
 */
int init_sem(int num, int val)
{	
	union semun myun;
/////////////////////////////
//	int shmid;
//	int semid;
//	int key2;
////////////////////////////////	
	myun.val = val;
	
	if((key2 = ftok("/app", 'i')) < 0)
	{
		syserr("ftok");
		return -1;
	}

	if((semid  = semget(key2, 1, 0666|IPC_CREAT)) < 0)
	{
		syserr("semget");
		exit(1);
	}
	DDEBUG(P_NORMAL,"<<SHMCTL>> get semid:%d\n",semid);
	if(semctl(semid, num, SETVAL, myun) < 0)
	{
		syserr("semctl");
		exit(1);
	}
	shmid = shmget(key2, sizeof(struct shm_addr), IPC_CREAT | 0666);
	if(-1 == shmid)
	{
		syserr("shmget");
		return -1;
	}
	DDEBUG(P_NORMAL,"<<SHMCTL>> get shmid:%d\n",shmid);



//////////////////////////////////////////////////
	if((shm_buf = (struct shm_addr*)shmat(shmid, NULL, 0)) == (void*)-1 )
	{
		syserr("shmat");
		exit(1);
	}
	DDEBUG(P_NORMAL,"<<SHMCTL>> get shm_buf:%p\n",shm_buf);
/////////////////////////////////////////////////

	return 0;
}



/*切记shmget_env和shmset_env要同时使用，
 *所用共享内存操作应该在这两个函数中间使用
 */
int shmget_env(struct shm_addr **to) 
{ 
	sem_p(semid,0);
	*to = shm_buf;
	return 0; 
} 

int shmset_env(struct shm_addr *from) 
{ 
//	shmdt(from);
	sem_v(semid, 0);
	return 0; 
} 






/*
int shmset_env(struct shm_addr *from) 
{ 
	key_t key2;
	int shmid;
	int semid;	
	if((key2 = ftok("/app", 'i')) < 0)
	{
		syserr("ftok");
		return -1;
	}
	DDEBUG(P_NORMAL,"<<SHMCTL>> get key2(/app,i):%x\n",key2);
	shmid = shmget(key2, sizeof(struct shm_addr), IPC_CREAT | 0666);
	if(-1 == shmid)
	{
		syserr("shmget");
		return -1;
	}
	DDEBUG(P_NORMAL,"<<SHMCTL>> get shmid:%d\n",shmid);

	if((semid  = semget(key2, 1, 0666|IPC_CREAT)) < 0)
	{
		syserr("semget");
		exit(1);
	}

//	init_sem(semid,0,1);
	struct shm_addr *shm_buf;
	if((shm_buf = (struct shm_addr*)shmat(shmid, NULL, 0)) == (void*)-1 )
	{
		syserr("shmat");
		exit(1);
	}
	sem_p(semid,0);

	memcpy(shm_buf,from,sizeof(struct shm_addr));
	sem_v(semid, 0);

	return 0; 
} 




int shmget_env(struct shm_addr *to) 
{ 
	key_t key2;
	int shmid;
	int semid;
	if((key2 = ftok("/app", 'i')) < 0)
	{
		syserr("ftok");
		return -1;
	}
	DDEBUG(P_NORMAL,"<<SHMCTL>> get key2(/app,i):%x\n",key2);
	
	shmid = shmget(key2, sizeof(struct shm_addr), IPC_CREAT | 0666);
	if(-1 == shmid)
	{
		syserr("shmget");
		return -1;
	}
	DDEBUG(P_NORMAL,"<<SHMCTL>> get shmid:%d\n",shmid);

	if((semid  = semget(key2, 1, 0666|IPC_CREAT)) < 0)
	{
		syserr("semget");
		exit(1);
	}
	DDEBUG(P_NORMAL,"<<SHMCTL>> get semid:%d\n",semid);
//	init_sem(semid,0,1);
	struct shm_addr *shm_buf;
	if((shm_buf = (struct shm_addr*)shmat(shmid, NULL, 0)) == (void*)-1 )
	{
		syserr("shmat");
		exit(1);
	}
	sem_p(semid,0);
	memcpy(to,shm_buf,sizeof(struct shm_addr));
	sem_v(semid, 0);

	return 0; 
} 




*/
